package io.webfolder.cdp.command;

import java.util.List;

import com.google.gson.reflect.TypeToken;

import io.webfolder.cdp.session.SessionInvocationHandler;
import io.webfolder.cdp.type.browser.Bounds;
import io.webfolder.cdp.type.browser.GetVersionResult;
import io.webfolder.cdp.type.browser.GetWindowForTargetResult;
import io.webfolder.cdp.type.browser.Histogram;
import io.webfolder.cdp.type.browser.PermissionType;

public class BrowserImpl implements Browser {

	private static final String[] EMPTY_ARGS = new String[] {};
	private static final Object[] EMPTY_VALUES = new Object[] {};
	private static final TypeToken<List<String>> GET_BROWSER_COMMAND_LINE = new TypeToken<List<String>>() {
	};
	private static final TypeToken<List<Histogram>> GET_HISTOGRAMS = new TypeToken<List<Histogram>>() {
	};
	private final SessionInvocationHandler handler;

	public BrowserImpl(SessionInvocationHandler handler) {
		this.handler = handler;
	}

	@Override
	public void close() {
		handler.invoke("Browser", "close", "Browser.close", null, void.class, null, true, false, false, EMPTY_ARGS,
				EMPTY_VALUES);
	}

	@Override
	public void crash() {
		handler.invoke("Browser", "crash", "Browser.crash", null, void.class, null, true, false, false, EMPTY_ARGS,
				EMPTY_VALUES);
	}

	@Override
	public void crashGpuProcess() {
		handler.invoke("Browser", "crashGpuProcess", "Browser.crashGpuProcess", null, void.class, null, true, false,
				false, EMPTY_ARGS, EMPTY_VALUES);
	}

	@Override
	@java.lang.SuppressWarnings("unchecked")
	public List<String> getBrowserCommandLine() {
		return (List<String>) handler.invoke("Browser", "getBrowserCommandLine", "Browser.getBrowserCommandLine",
				"arguments", List.class, GET_BROWSER_COMMAND_LINE.getType(), false, false, false, EMPTY_ARGS,
				EMPTY_VALUES);
	}

	@Override
	public Histogram getHistogram(String name) {
		return (Histogram) handler.invoke("Browser", "getHistogram", "Browser.getHistogram", "histogram",
				Histogram.class, null, false, false, false, new String[] { "name" }, new Object[] { name });
	}

	@Override
	public Histogram getHistogram(String name, Boolean delta) {
		return (Histogram) handler.invoke("Browser", "getHistogram", "Browser.getHistogram", "histogram",
				Histogram.class, null, false, false, false, new String[] { "name", "delta" },
				new Object[] { name, delta });
	}

	@Override
	@java.lang.SuppressWarnings("unchecked")
	public List<Histogram> getHistograms() {
		return (List<Histogram>) handler.invoke("Browser", "getHistograms", "Browser.getHistograms", "histograms",
				List.class, GET_HISTOGRAMS.getType(), false, false, false, EMPTY_ARGS, EMPTY_VALUES);
	}

	@Override
	@java.lang.SuppressWarnings("unchecked")
	public List<Histogram> getHistograms(String query, Boolean delta) {
		return (List<Histogram>) handler.invoke("Browser", "getHistograms", "Browser.getHistograms", "histograms",
				List.class, GET_HISTOGRAMS.getType(), false, false, false, new String[] { "query", "delta" },
				new Object[] { query, delta });
	}

	@Override
	public GetVersionResult getVersion() {
		return (GetVersionResult) handler.invoke("Browser", "getVersion", "Browser.getVersion", null,
				GetVersionResult.class, null, false, false, false, EMPTY_ARGS, EMPTY_VALUES);
	}

	@Override
	public Bounds getWindowBounds(Integer windowId) {
		return (Bounds) handler.invoke("Browser", "getWindowBounds", "Browser.getWindowBounds", "bounds", Bounds.class,
				null, false, false, false, new String[] { "windowId" }, new Object[] { windowId });
	}

	@Override
	public GetWindowForTargetResult getWindowForTarget() {
		return (GetWindowForTargetResult) handler.invoke("Browser", "getWindowForTarget", "Browser.getWindowForTarget",
				null, GetWindowForTargetResult.class, null, false, false, false, EMPTY_ARGS, EMPTY_VALUES);
	}

	@Override
	public GetWindowForTargetResult getWindowForTarget(String targetId) {
		return (GetWindowForTargetResult) handler.invoke("Browser", "getWindowForTarget", "Browser.getWindowForTarget",
				null, GetWindowForTargetResult.class, null, false, false, false, new String[] { "targetId" },
				new Object[] { targetId });
	}

	@Override
	public void grantPermissions(String origin, PermissionType permissions) {
		handler.invoke("Browser", "grantPermissions", "Browser.grantPermissions", null, void.class, null, true, false,
				false, new String[] { "origin", "permissions" }, new Object[] { origin, permissions });
	}

	@Override
	public void grantPermissions(String origin, PermissionType permissions, String browserContextId) {
		handler.invoke("Browser", "grantPermissions", "Browser.grantPermissions", null, void.class, null, true, false,
				false, new String[] { "origin", "permissions", "browserContextId" },
				new Object[] { origin, permissions, browserContextId });
	}

	@Override
	public void resetPermissions() {
		handler.invoke("Browser", "resetPermissions", "Browser.resetPermissions", null, void.class, null, true, false,
				false, EMPTY_ARGS, EMPTY_VALUES);
	}

	@Override
	public void resetPermissions(String browserContextId) {
		handler.invoke("Browser", "resetPermissions", "Browser.resetPermissions", null, void.class, null, true, false,
				false, new String[] { "browserContextId" }, new Object[] { browserContextId });
	}

	@Override
	public void setDockTile() {
		handler.invoke("Browser", "setDockTile", "Browser.setDockTile", null, void.class, null, true, false, false,
				EMPTY_ARGS, EMPTY_VALUES);
	}

	@Override
	public void setDockTile(String badgeLabel, String image) {
		handler.invoke("Browser", "setDockTile", "Browser.setDockTile", null, void.class, null, true, false, false,
				new String[] { "badgeLabel", "image" }, new Object[] { badgeLabel, image });
	}

	@Override
	public void setWindowBounds(Integer windowId, Bounds bounds) {
		handler.invoke("Browser", "setWindowBounds", "Browser.setWindowBounds", null, void.class, null, true, false,
				false, new String[] { "windowId", "bounds" }, new Object[] { windowId, bounds });
	}
}